"""
verison: 
+ v1:读取inp,节点,单元,集合的信息
+ v2: 增加读取*surface得到信息,每一个surface对应一个(m,2)的数组,第一列是单元label,第二列是单元faceId
"""

import numpy as np
import re
from typing import Tuple,Dict

def InpReader(file_path:str)->Tuple[np.ndarray,np.ndarray,Dict[str,np.ndarray],Dict[str,np.ndarray],Dict[str,np.ndarray]]:
    """
    读取Abaqus INP文件,解析节点、单元、Nset和Elset数据(数据全是inp的,没有修改,因此,索引是从1开始的)   .**注意:返回的节点集合名称全是小写**
    
    ### 示例用法
    
    ```python
    
    file_path = 'EXAMPLE.inp'  # 替换为你的INP文件路径
    nodes, elements, nsets, elsets = read_abaqus_inp(file_path)
    ```
    
    参数:
        file_path (str): INP文件的路径.

    返回:
        + nodes (numpy.ndarray): 节点数据,形状为 (n_nodes, 4),列分别为节点编号和坐标.
        + elements (numpy.ndarray): 单元数据,形状为 (n_elements, n_nodes_per_element + 1),列分别为单元编号和节点编号.
        + nsets (dict): 节点集合数据,键为集合名称,值为包含节点编号的numpy数组.
        + elsets (dict): 单元集合数据,键为集合名称,值为包含单元编号的numpy数组.
    """
    nodes = []
    elements = []
    nsets = {}
    elsets = {}
    current_section = None
    surfaces = {}
    Generate=False
    current_surface = None
    with open(file_path, 'r',encoding='utf-8') as file:
        for line in file.readlines():
            line= line.replace(' ','') # 去掉所有的空格
            line = line.strip()
            if line.lower().startswith('*node'):
                current_section = 'Node'
                continue
            elif line.lower().startswith('*element'):
                current_section = 'Element'
                continue
            elif line.lower().startswith('*nset'):
                current_section = 'Nset'
                if 'generate' in line.lower():
                    Generate=True
                else:
                    Generate=False
                set_name = re.search(r'nset=([a-zA-Z0-9_]+)', line.lower()).group(1)
                nsets[set_name] = []
                continue
            elif line.lower().startswith('*elset'):
                current_section = 'Elset'
                if 'generate' in line.lower():
                    Generate=True
                else:
                    Generate=False
                set_name = re.search(r'elset=([a-zA-Z0-9_]+)', line.lower()).group(1)
                elsets[set_name] = []
                continue
            elif line.lower().startswith('*surface'):
                current_section = 'Surface'
                surface_name = re.search(r'name=([a-zA-Z0-9_]+)', line.lower()).group(1)
                surface_type = re.search(r'type=([a-zA-Z0-9_]+)', line.lower()).group(1)
                surfaces[surface_name] = []
                current_surface = surface_name
                continue
            elif line.startswith('**'):
                current_section = None
                continue
            if current_section == 'Node':
                node_data = line.split(',')
                if len(node_data) > 1:  # 确保是有效数据行
                    node_id = int(node_data[0])
                    node_coords = [float(coord) for coord in node_data[1:]]
                    nodes.append([node_id] + node_coords)

            elif current_section == 'Element':
                element_data = line.split(',')
                if len(element_data) > 1:  # 确保是有效数据行
                    element_id = int(element_data[0])
                    element_nodes = [int(node) for node in element_data[1:]]
                    elements.append([element_id] + element_nodes)

            elif current_section == 'Nset':
                nset_data = line.split(',')
                if Generate:
                    # print(nset_data)
                    start,end,sep=list(map(int,nset_data))
                    nsets[set_name].extend(np.arange(start,end+0.1,sep,dtype=int).tolist())
                else:
                    nsets[set_name].extend([int(node) for node in nset_data if node.strip()])

            elif current_section == 'Elset':
                elset_data = line.split(',')
                if Generate:
                    start,end,sep=list(map(int,elset_data))
                    elsets[set_name].extend(np.arange(start,end+0.1,sep,dtype=int).tolist())
                else:
                    elsets[set_name].extend([int(element) for element in elset_data if element.strip()])
            
            elif current_section == 'Surface':
                l1_el_set,l2_face_id= line.split(',')
                for e_idx in elsets[l1_el_set.lower()]:
                    # {surface_name: [[elem_label, elem_face_id],...],...}
                    if e_idx:
                        surfaces[current_surface].append([int(e_idx), int(l2_face_id[-1])])

    # 将节点和单元数据转换为numpy数组
    nodes = np.array(nodes, dtype=float)
    nodes[:,0].astype(int)  # 节点编号必须为整数
    elements = np.array(elements, dtype=int)
    # 将Nset和Elset数据转换为numpy数组
    for set_name in nsets.keys():
        nsets[set_name] = np.array(nsets[set_name], dtype=int)
    for set_name in elsets.keys():
        elsets[set_name] = np.array(elsets[set_name], dtype=int)
    # 将surface数据集转换为(m,2)的数组
    for s in surfaces.keys():
        surfaces[s]=np.array(surfaces[s],dtype=int)
    return nodes, elements, nsets, elsets,surfaces

def TrussAnalysisConfigReader(json_file,):
    """
    读取json文件,解析桁架单元分析的配置文件信息(加载,边界,输出量等等).
    """
    pass